---
title: useRef Hook
description: "Details about the useRef React hook in ReScript"
canonical: "/docs/react/hooks-ref"
section: "Hooks & State Management"
order: 6
---

# useRef

<Intro>

The `useRef` hooks creates and manages mutable containers inside your React component.

</Intro>

## Usage

<CodeTab labels={["ReScript", "JS Output"]}>

```res
let refContainer = React.useRef(initialValue)
```

```js
var button = React.useRef(null);
React.useRef(0);
```

</CodeTab>

`React.useRef` returns a mutable ref object whose `.current` record field is initialized to the passed argument (`initialValue`). The returned object will persist for the full lifetime of the component.

Essentially, a `React.ref` is like a "box" that can hold a mutable value in its `.current` record field.

You might be familiar with refs primarily as a way to access the DOM. If you pass a ref object to React with `<div ref={ReactDOM.Ref.domRef(myRef)} />`, React will set its `.current` property to the corresponding DOM node whenever that node changes.

However, `useRef()` is useful for more than the ref attribute. It's handy for keeping any mutable value around similar to how you’d use instance fields in classes.

This works because `useRef()` creates a plain JavaScript object. The only difference between `useRef()` and creating a `{current: ...}` object yourself is that useRef will give you the same ref object on every render.

Keep in mind that `useRef` doesn't notify you when its content changes. Mutating the `.current` record field doesn't cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a [callback ref](./refs-and-the-dom.mdx#callback-refs) instead.

More infos on direct DOM manipulation can be found in the [Refs and the DOM](./refs-and-the-dom.mdx) section.

## Examples

### Managing Focus for a Text Input

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
// TextInputWithFocusButton.res

@send external focus: Dom.element => unit = "focus"

@react.component
let make = () => {
  let inputEl = React.useRef(Nullable.null)

  let onClick = _ => {
    inputEl.current->Nullable.forEach(input => input->focus)
  }

  <>
    <input ref={ReactDOM.Ref.domRef(inputEl)} type_="text" />
    <button onClick> {React.string("Focus the input")} </button>
  </>
}
```

```js
function TextInputWithFocusButton(Props) {
  var inputEl = React.useRef(null);
  var onClick = function (param) {
    Core__Nullable.forEach(inputEl.current, function (input) {
      input.focus();
    });
  };
  return React.createElement(
    React.Fragment,
    {},
    React.createElement("input", {
      ref: Caml_option.some(inputEl),
      type: "text",
    }),
    React.createElement(
      "button",
      {
        onClick: onClick,
      },
      "Focus the input",
    ),
  );
}
```

</CodeTab>

### Using a Callback Ref

Reusing the example from our [Refs and the DOM](./refs-and-the-dom.mdx#callback-refs) section:

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
// CustomTextInput.res

@send external focus: Dom.element => unit = "focus"

@react.component
let make = () => {
  let textInput = React.useRef(Nullable.null)
  let setTextInputRef = element => {
    textInput.current = element;
    None
  }

  let focusTextInput = _ => {
    textInput.current->Nullable.forEach(input => input->focus)
  }

  <div>
    <input type_="text" ref={ReactDOM.Ref.callbackDomRef(setTextInputRef)} />
    <input
      type_="button" value="Focus the text input" onClick={focusTextInput}
    />
  </div>
}
```

```js
function CustomTextInput(Props) {
  var textInput = React.useRef(null);
  var setTextInputRef = function (element) {
    textInput.current = element;
  };
  var focusTextInput = function (param) {
    Core__Nullable.forEach(textInput.current, function (input) {
      input.focus();
    });
  };
  return React.createElement(
    "div",
    undefined,
    React.createElement("input", {
      ref: Caml_option.some(setTextInputRef),
      type: "text",
    }),
    React.createElement("input", {
      type: "button",
      value: "Focus the text input",
      onClick: focusTextInput,
    }),
  );
}
```

</CodeTab>
